home *** CD-ROM | disk | FTP | other *** search
-
- Free Information Xchange '98 presents:
-
- Get Medieval - CD crack by Static Vengeance - Sep 12, 1998
-
- Requirementes:
- Hex editor and full game install
- W32Dasm if you wish to follow along
-
- Get Medieval is a new 1998 version of Gauntlet produced by Monolith. The game is great if you
- like Gaunlet and is done well. I, of course, want to be able to play the game without the CD so I looked
- into cracking this game. The CD check is much like that found in Captain Claw (or just "Claw") which is
- also produced by Monolith. Also, once again this provides me with the oppertunity to write up another
- tutorial for you to read and learn from. So follow along with me as we go on our own adventure with Get
- Medieval's copy protection, and find out how to slay this evil beast.
- To get started you'll need some tools. The two tools I used the most are W32Dasm from RUSOft and
- a Hex editor. The Hex editor I use is HEdit, only becuase this is the first one I used. However any hex
- editor will work fine. Next you'll need to disassemble the exe file and then we can get started. After
- you have W32Dasm up and running and have disassembled Medieval.exe, go up the menu bar and select "Refs"
- and then down to String Data References from the drop down menu. Now you get the Refs pop up box. From
- here grab the slider bar and start looking for interesting things. Right away you'll see a a ref like
- "%c:\GAME\MEDIEVAL.EXE" I've seen this in many copy protection routines, so I double clicked on this one
- first. This put me in the middle of the following routine:
-
- * Referenced by a CALL at Addresses:
- |:00410790 , :0042C075 <-- Called by two locations
- |
- :004107F0 64A100000000 mov eax, dword ptr fs:[00000000]
- :004107F6 6AFF push FFFFFFFF
- :004107F8 683B484D00 push 004D483B
- :004107FD 50 push eax
- :004107FE A0C86A5000 mov al, byte ptr [00506AC8]
- :00410803 64892500000000 mov dword ptr fs:[00000000], esp
- :0041080A 81EC60040000 sub esp, 00000460
- :00410810 53 push ebx
- :00410811 33DB xor ebx, ebx
- :00410813 56 push esi
- :00410814 3AC3 cmp al, bl
- :00410816 57 push edi
- :00410817 0F852C010000 jne 00410949
- :0041081D 899C2450010000 mov dword ptr [esp+00000150], ebx
- :00410824 53 push ebx
- :00410825 6802000080 push 80000002
- :0041082A 53 push ebx
-
- * Possible StringData Ref from Data Obj ->"1.0"
- |
- :0041082B 6860574F00 push 004F5760
-
- * Possible StringData Ref from Data Obj ->"Get Medieval"
- |
- :00410830 6850574F00 push 004F5750
-
- * Possible StringData Ref from Data Obj ->"Monolith Productions"
- |
- :00410835 6838574F00 push 004F5738
- :0041083A 8D8C2468010000 lea ecx, dword ptr [esp+00000168]
- :00410841 899C248C040000 mov dword ptr [esp+0000048C], ebx
- :00410848 E853100700 call 004818A0
-
- * Reference To: KERNEL32.GetDriveTypeA, Ord:00DFh <-- Commonly used in CD checks
- |
- :0041084D 8B3DD0D04D00 mov edi, dword ptr [004DD0D0]
- :00410853 85C0 test eax, eax
- :00410855 0F8480000000 je 004108DB <-- 00 means "Drive Cannot Be determined"
- :0041085B 8D44240C lea eax, dword ptr [esp+0C]
- :0041085F 53 push ebx
- :00410860 8D4C2414 lea ecx, dword ptr [esp+14]
- :00410864 50 push eax
- :00410865 51 push ecx
-
- * Possible StringData Ref from Data Obj ->"CdRom Drive"
- |
- :00410866 68C8664F00 push 004F66C8
- :0041086B 8D8C2460010000 lea ecx, dword ptr [esp+00000160]
- :00410872 C744241C1E000000 mov [esp+1C], 0000001E
- :0041087A 885C2420 mov byte ptr [esp+20], bl
- :0041087E E85D120700 call 00481AE0 <-- Check against CD Rom drive
- :00410883 85C0 test eax, eax
- :00410885 7454 je 004108DB
- :00410887 8A442410 mov al, byte ptr [esp+10]
- :0041088B 3C14 cmp al, 14
- :0041088D 7E4C jle 004108DB
- :0041088F 0FBEF0 movsx esi, al
- :00410892 56 push esi
- :00410893 8D542434 lea edx, dword ptr [esp+34]
-
- * Possible StringData Ref from Data Obj ->"%c:\" <-- Start with C:\ and work through all drives
- | <-- Again, "%c:\" is commonly used in CD checks
- :00410897 68C0664F00 push 004F66C0
- :0041089C 52 push edx
- :0041089D 8AD8 mov bl, al
- :0041089F E83CB90500 call 0046C1E0
- :004108A4 83C40C add esp, 0000000C
- :004108A7 8D442430 lea eax, dword ptr [esp+30]
- :004108AB 50 push eax
- :004108AC FFD7 call edi
- :004108AE 83F805 cmp eax, 00000005
- :004108B1 7528 jne 004108DB
- :004108B3 56 push esi
- :004108B4 8D4C2454 lea ecx, dword ptr [esp+54]
-
- * Possible StringData Ref from Data Obj ->"%c:\GAME\MEDIEVAL.EXE" <-- Path name on CD for the EXE
- | <-- The "c" will get updated to CD rom letter
- :004108B8 68D4664F00 push 004F66D4
- :004108BD 51 push ecx
- :004108BE E81DB90500 call 0046C1E0
- :004108C3 83C40C add esp, 0000000C
- :004108C6 8D542450 lea edx, dword ptr [esp+50]
- :004108CA 52 push edx
- :004108CB E8D0FEFFFF call 004107A0
- :004108D0 83C404 add esp, 00000004
- :004108D3 85C0 test eax, eax
- :004108D5 0F8586000000 jne 00410961 <-- Jump down to exit section of routine
-
- * Referenced by a (U)nconditional or (C)onditional Jump at Addresses:
- |:00410855(C), :00410885(C), :0041088D(C), :004108B1(C)
- |
- :004108DB B341 mov bl, 41
-
- * Referenced by a (U)nconditional or (C)onditional Jump at Address:
- |:0041092E(C)
- |
- :004108DD 0FBEF3 movsx esi, bl
- :004108E0 56 push esi
- :004108E1 8D842470030000 lea eax, dword ptr [esp+00000370]
-
- * Possible StringData Ref from Data Obj ->"%c:\" <-- Starting over with checks
- |
- :004108E8 68C0664F00 push 004F66C0
- :004108ED 50 push eax
- :004108EE E8EDB80500 call 0046C1E0
- :004108F3 83C40C add esp, 0000000C
- :004108F6 8D8C246C030000 lea ecx, dword ptr [esp+0000036C]
- :004108FD 51 push ecx
- :004108FE FFD7 call edi
- :00410900 83F805 cmp eax, 00000005
- :00410903 7524 jne 00410929
- :00410905 56 push esi
- :00410906 8D542454 lea edx, dword ptr [esp+54]
-
- * Possible StringData Ref from Data Obj ->"%c:\GAME\MEDIEVAL.EXE" <-- File we're looking for
- |
- :0041090A 68D4664F00 push 004F66D4
- :0041090F 52 push edx
- :00410910 E8CBB80500 call 0046C1E0
- :00410915 83C40C add esp, 0000000C
- :00410918 8D442450 lea eax, dword ptr [esp+50]
- :0041091C 50 push eax
- :0041091D E87EFEFFFF call 004107A0
- :00410922 83C404 add esp, 00000004
- :00410925 85C0 test eax, eax
- :00410927 7538 jne 00410961 <-- Take this jump for successful CD check
-
- * Referenced by a (U)nconditional or (C)onditional Jump at Address:
- |:00410903(C)
- |
- :00410929 FEC3 inc bl <-- Increase the total number of tries
- :0041092B 80FB5A cmp bl, 5A <-- Max number of atempts for CD check
- :0041092E 7EAD jle 004108DD <-- If less the max #, keep trying
- :00410930 8D8C2450010000 lea ecx, dword ptr [esp+00000150]
- :00410937 C7842474040000FFFFFFFF mov dword ptr [esp+00000474], FFFFFFFF
- :00410942 E879100700 call 004819C0
- :00410947 32C0 xor al, al <-- Zero out al for failed CD check
-
- * Referenced by a (U)nconditional or (C)onditional Jump at Addresses:
- |:00410817(C), :00410980(U)
- |
- :00410949 8B8C246C040000 mov ecx, dword ptr [esp+0000046C]
- :00410950 5F pop edi
- :00410951 5E pop esi
- :00410952 64890D00000000 mov dword ptr fs:[00000000], ecx
- :00410959 5B pop ebx
- :0041095A 81C46C040000 add esp, 0000046C
- :00410960 C3 ret
-
- * Referenced by a (U)nconditional or (C)onditional Jump at Addresses: <-- Need to get here for passed CD check
- |:004108D5(C), :00410927(C)
- |
- :00410961 8D8C2450010000 lea ecx, dword ptr [esp+00000150]
- :00410968 881DC86A5000 mov byte ptr [00506AC8], bl
- :0041096E C7842474040000FFFFFFFF mov dword ptr [esp+00000474], FFFFFFFF
- :00410979 E842100700 call 004819C0
- :0041097E 8AC3 mov al, bl <-- Move a non-zero value to al, bl=number of tries
- :00410980 EBC7 jmp 00410949 <-- Jump back up to the exit section
- :00410982 90 nop
- :00410983 90 nop
- :00410984 90 nop
-
- That's the basics of what the CD check is doing. Now we'll look at the two callers to find
- the place we will want to place our patch. So let's first check out the code around 410790:
-
- * Referenced by a CALL at Addresses:
- |:0041064F , :00410719 , :0041072D <-- Called three times
- |
- :00410790 E85B000000 call 004107F0 <-- Read the exe off the CD
- :00410795 33C9 xor ecx, ecx <-- Zero out the ecx
- :00410797 84C0 test al, al <-- Test for the result of the CD check
- :00410799 0F95C1 setne cl <-- Non-zero in al will result in cl = 01
- :0041079C 8BC1 mov eax, ecx <-- Move the the "new" value into eax
- :0041079E C3 ret <-- Return to the caller
-
- Alright, that's pretty short. So lets go back one step and check out the three calls from
- above. We'll check out the code surounding the three calls to see what needs to be done to kill
- this call to the CD check. What we're looking for is a good spot to put a simple patch, idealy it's
- place where we could make a single edit. So let's keep going with this one.
-
- * Referenced by a CALL at Address:
- |:0046A729 <-- Called from one spot!
- |
- :00410630 64A100000000 mov eax, dword ptr fs:[00000000]
- :00410636 6AFF push FFFFFFFF
- :00410638 681B484D00 push 004D481B
- :0041063D 50 push eax
- :0041063E 64892500000000 mov dword ptr fs:[00000000], esp
- :00410645 81ECC0000000 sub esp, 000000C0
- :0041064B 53 push ebx
- :0041064C 55 push ebp
- :0041064D 56 push esi
- :0041064E 57 push edi
- :0041064F E83C010000 call 00410790 <-- The first call to the above routine
- :00410654 85C0 test eax, eax
- :00410656 740A je 00410662 <-- Zero in eax means the CD check failed
- :00410658 B801000000 mov eax, 00000001 <-- Setup for a sucessful CD check
- :0041065D E912010000 jmp 00410774 <-- Jump down to the exit section
-
- * Referenced by a (U)nconditional or (C)onditional Jump at Address:
- |:00410656(C)
- |
- :00410662 8BAC24E0000000 mov ebp, dword ptr [esp+000000E0]
-
- * Reference To: USER32.LoadStringA, Ord:0183h
- |
- :00410669 8B1D78D44D00 mov ebx, dword ptr [004DD478]
-
- * Referenced by a (U)nconditional or (C)onditional Jump at Address:
- |:0041074E(U)
- |
- :0041066F 8B0DD8005200 mov ecx, dword ptr [005200D8]
- :00410675 8D442450 lea eax, dword ptr [esp+50]
- :00410679 6A7C push 0000007C
- :0041067B 50 push eax
-
- * Possible Ref to Menu: MEDIEVAL, Item: "Single 1"
- |
- * Possible Reference to String Resource ID=32804: "Please insert the Get Medieval CD-ROM into the drive."
- |
- :0041067C 6824800000 push 00008024
- :00410681 51 push ecx
- :00410682 FFD3 call ebx
- :00410684 85C0 test eax, eax
- :00410686 7524 jne 004106AC
-
- * Possible StringData Ref from Data Obj ->"Please insert the game CD-ROM " <-- This says it all, and is
- ->"into the drive." <-- what we never want to see
- |
- :00410688 BF90664F00 mov edi, 004F6690
- :0041068D 83C9FF or ecx, FFFFFFFF
- :00410690 F2 repnz
- :00410691 AE scasb
- :00410692 F7D1 not ecx
- :00410694 2BF9 sub edi, ecx
- :00410696 8D542450 lea edx, dword ptr [esp+50]
- :0041069A 8BC1 mov eax, ecx
- :0041069C 8BF7 mov esi, edi
- :0041069E 8BFA mov edi, edx
- :004106A0 C1E902 shr ecx, 02
- :004106A3 F3 repz
- :004106A4 A5 movsd
- :004106A5 8BC8 mov ecx, eax
- :004106A7 83E103 and ecx, 00000003
- :004106AA F3 repz
- :004106AB A4 movsb
-
- * Referenced by a (U)nconditional or (C)onditional Jump at Address:
- |:00410686(C)
- |
- :004106AC 8B15D8005200 mov edx, dword ptr [005200D8]
- :004106B2 8D4C2410 lea ecx, dword ptr [esp+10]
- :004106B6 6A3E push 0000003E
- :004106B8 51 push ecx
-
- * Possible Reference to String Resource ID=32771: "Get Medieval"
- |
- :004106B9 6803800000 push 00008003
- :004106BE 52 push edx
- :004106BF FFD3 call ebx
- :004106C1 85C0 test eax, eax
- :004106C3 7524 jne 004106E9
-
- * Possible StringData Ref from Data Obj ->"Get Medieval"
- |
- :004106C5 BF50574F00 mov edi, 004F5750
- :004106CA 83C9FF or ecx, FFFFFFFF
- :004106CD F2 repnz
- :004106CE AE scasb
- :004106CF F7D1 not ecx
- :004106D1 2BF9 sub edi, ecx
- :004106D3 8D542410 lea edx, dword ptr [esp+10]
- :004106D7 8BC1 mov eax, ecx
- :004106D9 8BF7 mov esi, edi
- :004106DB 8BFA mov edi, edx
- :004106DD C1E902 shr ecx, 02
- :004106E0 F3 repz
- :004106E1 A5 movsd
- :004106E2 8BC8 mov ecx, eax
- :004106E4 83E103 and ecx, 00000003
- :004106E7 F3 repz
- :004106E8 A4 movsb
-
- * Referenced by a (U)nconditional or (C)onditional Jump at Address:
- |:004106C3(C)
- |
- :004106E9 8D4C2410 lea ecx, dword ptr [esp+10]
- :004106ED 6A31 push 00000031
- :004106EF 8D542454 lea edx, dword ptr [esp+54]
- :004106F3 51 push ecx
- :004106F4 52 push edx
- :004106F5 55 push ebp
-
- * Reference To: USER32.MessageBoxA, Ord:0195h
- |
- :004106F6 FF1574D44D00 Call dword ptr [004DD474]
- :004106FC 83F801 cmp eax, 00000001
- :004106FF 7571 jne 00410772
- :00410701 E8331E0C00 call 004D2539
- :00410706 8B4804 mov ecx, dword ptr [eax+04]
- :00410709 E82E890B00 call 004C903C
- :0041070E C78424D800000000000000 mov dword ptr [esp+000000D8], 00000000
- :00410719 E872000000 call 00410790 <-- Second call to 410790
- :0041071E 85C0 test eax, eax
- :00410720 7531 jne 00410753
- :00410722 68E8030000 push 000003E8
-
- * Reference To: KERNEL32.Sleep, Ord:023Fh
- |
- :00410727 FF1560D24D00 Call dword ptr [004DD260]
- :0041072D E85E000000 call 00410790 <-- The last call to 410790
- :00410732 85C0 test eax, eax
- :00410734 C78424D8000000FFFFFFFF mov dword ptr [esp+000000D8], FFFFFFFF
- :0041073F 751D jne 0041075E
- :00410741 E8F31D0C00 call 004D2539
- :00410746 8B4804 mov ecx, dword ptr [eax+04]
- :00410749 E803890B00 call 004C9051
- :0041074E E91CFFFFFF jmp 0041066F
-
- * Referenced by a (U)nconditional or (C)onditional Jump at Address:
- |:00410720(C)
- |
- :00410753 C78424D8000000FFFFFFFF mov dword ptr [esp+000000D8], FFFFFFFF
-
- * Referenced by a (U)nconditional or (C)onditional Jump at Address:
- |:0041073F(C)
- |
- :0041075E E8D61D0C00 call 004D2539
- :00410763 8B4804 mov ecx, dword ptr [eax+04]
- :00410766 E8E6880B00 call 004C9051
- :0041076B B801000000 mov eax, 00000001 <-- Set up for a passed CD check
- :00410770 EB02 jmp 00410774 <-- Jump over "set for fail"
-
- * Referenced by a (U)nconditional or (C)onditional Jump at Address:
- |:004106FF(C)
- |
- :00410772 33C0 xor eax, eax <-- Set for a failed CD check
-
- * Referenced by a (U)nconditional or (C)onditional Jump at Addresses:
- |:0041065D(U), :00410770(U)
- |
- :00410774 8B8C24D0000000 mov ecx, dword ptr [esp+000000D0] <-- This the exit section
- :0041077B 5F pop edi
- :0041077C 5E pop esi
- :0041077D 5D pop ebp
- :0041077E 64890D00000000 mov dword ptr fs:[00000000], ecx
- :00410785 5B pop ebx
- :00410786 81C4CC000000 add esp, 000000CC
- :0041078C C3 ret
-
- Well we have gone through a lot of code, but it's down to just one call now, so let's check
- out the call 410630 and see if we can make our patch here:
-
- -- Program code --
- :0046A728 55 push ebp
- :0046A729 E8025FFAFF call 00410630 <-- Do the CD check
- :0046A72E 83C404 add esp, 00000004 <-- Adjust stack point for "ebp"
- :0046A731 85C0 test eax, eax <-- Test the pass/fail value in eax
- :0046A733 0F84CC020000 je 0046AA05 <-- Take this jump for failed check
- :0046A739 6854020000 push 00000254
- :0046A73E E86DDF0500 call 004C86B0
- :0046A743 83C404 add esp, 00000004
- :0046A746 89442414 mov dword ptr [esp+14], eax
- :0046A74A 3BC5 cmp eax, ebp
- -- Continuing programming code --
-
- Finally, we have a place to put a simple patch and we have sucessfully kill the FIRST
- call the CD check routine. My method to cracking programs is kill the call to the CD check
- and let the program code be able to continue normaly as though the CD check had passed. The
- "best" way to do that here, is to change the call 00410630 to mov eax, 00000001. This allows
- the program to "fall" through the je and let the game continue so we can play it. Now, lets
- go back and track down the second call and find a good location to place our other patch.
- Then we'll have a cracked game that can be played any time without the CD present.
-
- * Referenced by a CALL at Addresses:
- |:00426D21 , :00427391 , :0042C551 , :0042D461 <-- Called by four seperate places
- |
- :0042C060 56 push esi
- :0042C061 8BF1 mov esi, ecx
- :0042C063 8B86E0000000 mov eax, dword ptr [esi+000000E0] <-- Flag used for "CD check done"
- :0042C069 85C0 test eax, eax
- :0042C06B 7408 je 0042C075 <-- Jump down to the CD check below
- :0042C06D 8A86DC000000 mov al, byte ptr [esi+000000DC] <-- Else load the pass/fail flag
- :0042C073 5E pop esi
- :0042C074 C3 ret <-- Return to the caller
-
- * Referenced by a (U)nconditional or (C)onditional Jump at Address:
- |:0042C06B(C)
- |
- :0042C075 E87647FEFF call 004107F0 <-- Call the CD check
- :0042C07A 8886DC000000 mov byte ptr [esi+000000DC], al <-- Store the result in new flag
- :0042C080 C786E000000001000000 mov dword ptr [esi+000000E0], 00000001 <-- Show we have done the check
- :0042C08A 5E pop esi
- :0042C08B C3 ret <-- Return to the caller
-
- As you can see, a good place to put the second patch is right here at 42C075. Again changing
- the call to mov eax, 00000001 will overwrite the CD check and allow the program to continue running.
- After appling this patch along with the first one, you will have successfully cracked Get Medieval.
- Which is why started this little adventure. The steps need to crack this one are as follows:
-
- 1. Do a full game install
- 2. Make the following edits:
-
- Edit Medieval.exe
- =============================================
- Search for: E8 76 47 FE FF at offset 177,269
- Change to : B8 01 00 00 00
-
- Search for: E8 02 5F FA FF at offset 432,937
- Change to : B8 01 00 00 00
-
- Get Medieval is now FiX'ed and can be run from your hard drive without the CD being online.
- The last thing you can do is to copy Medieval.fec, which is the movie file. Just copy this file to
- the main Medieval game directory and the program will find it and use it. This is one of the most
- funny intro movies I have ever seen. I just love the comments made by the four game characters, it
- made me bust out laughing. This is of course optional and not needed to play the game, but I think
- it's worth the 42 megs it takes up on the hard drive.
-
- Well that concludes this tutorial, now go Get Medieval on someone!
-
- Static Vengeance
-
- Get Medieval Cheat Codes (same as Claw)
- ---------------------------------------
- mpkfa God mode
- mppos Global position
- mpfps Show frames per second
-